package com.personal.common.util;

/**
 * SSH4
 * d.java
 * Sep 27, 2009
 */

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
 * 
 * 文件操作
 */
@SuppressWarnings({"deprecation", "resource", "unused"})
public class FileUtil {

	private final static Logger logger = Logger.getLogger(FileUtil.class);

	/**
	 * 读取文件内容在线查看
	 */
	public static String viewFileContent(String path) throws Exception {

		StringBuffer str = new StringBuffer();
		File file = new File(path);
		// 判断文件是否存在，存在则读取出来，不存在则返回null
		if (file.exists()) {
			FileReader fr = new FileReader(file);
			BufferedReader br = new BufferedReader(fr);
			String s;
			while ((s = br.readLine()) != null) {
				str.append(s + "<br>");
			}
		} else {
			return null;
		}

		return str.toString();
	}

	/**
	 * 复制指定源文件到目的目录
	 * 
	 * @param fileNames
	 *            源文件名数组
	 * @param src
	 *            源目录
	 * @param dest
	 *            目的目录
	 * @throws IOException
	 */
	public static void copyFiles(String[] fileNames, String dest) throws IOException {

		for (String fileName : fileNames) {

			copyDirectiory(fileName, dest);
		}

	}

	/**
	 * @param srcNames
	 *            源文件名
	 * @param destNames
	 *            新文件名
	 * @param dest
	 *            目的地
	 * @throws IOException
	 */
	public static void copyFilesNewNames(String[] srcNames, String[] destNames, String dest) throws IOException {

		File file = new File(dest);
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			for (File element : files) {
				element.delete();
			}
		}
		for (int i = 0; i < srcNames.length; i++) {
			copyDirectiory2(srcNames[i], dest + "/" + destNames[i]);
		}

	}

	public static boolean copyDirectiory2(String sourceFile, String desFile) throws IOException {

		logger.info("copysrc:" + sourceFile);
		logger.info("copydest:" + desFile);

		File source = new File(sourceFile);
		if (!source.exists()) {
			logger.info(source.getAbsolutePath() + "========源文件不存在！=======");
			// return false;
		}

		FileInputStream input = null;
		FileOutputStream output = null;
		try {
			if (source.isFile()) {
				// 如果是文件 则读源文件 写入目标文件
				input = new FileInputStream(source);
				output = new FileOutputStream(new File(desFile));
				byte[] b = new byte[1024 * 5];
				int len;
				while ((len = input.read(b)) != -1) { // 读文件
					output.write(b, 0, len); // 向目标文件写文件
				}
				input.close();
				output.flush();
				output.close();
			} else if (source.isDirectory()) {
				// 如果是文件夹 递归读取子文件或文件夹
				copyDirectiory2(sourceFile + "/" + source.getName(), desFile);
			}

			logger.info("copydest1:" + new File(desFile).getAbsolutePath());
			logger.info("copydest1 if exist:" + new File(desFile).exists());

			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			if (input != null) {
				input.close();
			}
			if (output != null) {
				output.close();
			}
		}
	}

	/**
	 * 复制指定源文件到目的目录
	 * 
	 * @param fileName
	 *            源文件名数组
	 * @param src
	 *            源目录
	 * @param dest
	 *            目的目录
	 * @throws IOException
	 */
	public static void copyFiles(String[] fileName, String[] src, String dest) throws IOException {

		File file = new File(dest);
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			for (File element : files) {
				element.delete();
			}
		}
		for (int i = 0; i < fileName.length; i++) {

			copyDirectiory(src[i] + "/" + fileName[i], dest);
		}
	}

	/**
	 * 复制指定源文件到目的目录
	 * 
	 * @param fileName
	 *            源文件名数组
	 * @param src
	 *            源目录
	 * @param dest
	 *            目的目录
	 * @param delete
	 *            是否删除目录中原有的文件
	 * @throws IOException
	 */
	public static void copyFiles(String[] fileName, String[] src, String dest, boolean delete) throws IOException {

		File file = new File(dest);
		if (delete && file.isDirectory()) {
			File[] files = file.listFiles();
			for (File element : files) {
				element.delete();
			}
		}
		for (int i = 0; i < fileName.length; i++) {

			copyDirectiory(src[i] + "/" + fileName[i], dest);
		}
	}

	/**
	 * @param fileName
	 * @param src
	 * @param dest
	 * @param delete
	 *            是否删除目录中原有的文件
	 * @throws IOException
	 */
	public static void copyFiles(Object[] fileName, Object[] src, String dest, boolean delete) throws IOException {

		File file = new File(dest);
		if (delete && file.isDirectory()) {
			File[] files = file.listFiles();
			for (File element : files) {
				element.delete();
			}
		}
		for (int i = 0; i < fileName.length; i++) {

			copyDirectiory(src[i] + "/" + fileName[i], dest);
		}
	}

	/**
	 * 文件夹拷贝，将源文件夹下的所有文件及其子文件夹（文件）拷贝到目标文件夹（文件）下
	 * 
	 * @param sourceFile
	 *            源文件
	 * @param desFile
	 *            目标文件
	 * @return
	 */
	public static boolean copyDirectiory(String sourceFile, String desFile) throws IOException {

		File source = new File(sourceFile);
		if (!source.exists()) {
			// return false;
		}
		File des = new File(desFile);
		if (!des.exists()) {
			des.mkdirs();// 不存在目标文件就创建
		}

		// File[] file = source.listFiles();
		FileInputStream input = null;
		FileOutputStream output = null;
		try {
			// for (File element : file) {
			if (source.isFile()) { // 如果是文件 则读源文件 写入目标文件
				input = new FileInputStream(source);
				output = new FileOutputStream(new File(desFile + "/" + source.getName()));
				byte[] b = new byte[1024 * 5];
				int len;
				while ((len = input.read(b)) != -1) { // 读文件
					output.write(b, 0, len); // 向目标文件写文件
				}
				input.close();
				output.flush();
				output.close();
			} else if (source.isDirectory()) { // 如果是文件夹 递归读取子文件或文件夹
				copyDirectiory(sourceFile + "/" + source.getName(), desFile + "/" + source.getName());
			}
			// }
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			if (input != null) {
				input.close();
			}
			if (output != null) {
				output.close();
			}
		}
	}

	/**
	 * 下载
	 * 
	 * @param response
	 * @param path
	 *            文件路径和名称
	 * @param filename
	 *            下载时显示的名称
	 * @throws IOException
	 */
	/*
	 * public static void downloadFile(HttpServletResponse response, String
	 * path, String filename) throws IOException {
	 * 
	 * response.reset(); response.setContentType("application/force-download");
	 * response.addHeader("Content-Disposition", "attachment;filename=" +
	 * URLEncoder.encode(filename, Constants.ENCODING_UTF8));
	 * 
	 * BufferedOutputStream output = null; FileInputStream fis = null;
	 * 
	 * try { output = new BufferedOutputStream(response.getOutputStream()); fis
	 * = new FileInputStream(path + filename);
	 * 
	 * byte[] b = new byte[1024]; int i = 0; while ((i = fis.read(b)) > 0) {
	 * output.write(b, 0, i); } } catch (Exception e) { e.printStackTrace(); }
	 * finally { if (fis != null) { fis.close(); fis = null; } if (output !=
	 * null) { output.close(); output = null; } }
	 * 
	 * }
	 */

	public static String getFileName(String imgSrcUrl) {

		String name = "";

		if (StringUtils.isBlank(imgSrcUrl)) {
			return "";
		}

		name = imgSrcUrl.substring(imgSrcUrl.lastIndexOf("/") + 1);

		if (StringUtils.isBlank(name)) {
			return "";
		}

		if (name.contains("?")) {
			name = name.substring(0, name.indexOf("?"));
		}

		return name;
	}

	public static String getFileExtName(String imgSrcUrl) {

		String name = "";

		if (StringUtils.isBlank(imgSrcUrl)) {
			return "";
		}

		name = imgSrcUrl.substring(imgSrcUrl.lastIndexOf("."));

		return name;
	}

	public static String getFileExtNameNoDot(String imgSrcUrl) {

		String name = "";

		if (StringUtils.isBlank(imgSrcUrl)) {
			return "";
		}

		name = imgSrcUrl.substring(imgSrcUrl.lastIndexOf(".") + 1);

		return name;
	}

	/**
	 * 保存远程图片到本地
	 * 
	 * @param imgSrcUrl
	 * @param saveFileName
	 * @return
	 * @throws IOException
	 */
	@Deprecated
	public static boolean saveImageOld(String imgSrcUrl, String saveFileName) throws IOException {

		BufferedOutputStream output = null;
		DataInputStream di = null;
		FileOutputStream fo = null;

		URLConnection urlConnection = new URL(imgSrcUrl).openConnection();
		urlConnection.connect();

		/* String userAgent = JsoupUtil.getRandomUserAgent(); */

		di = new DataInputStream(urlConnection.getInputStream());
		fo = new FileOutputStream(saveFileName);
		BufferedInputStream inputStream = new BufferedInputStream(di);

		try {
			output = new BufferedOutputStream(fo);
			byte[] b = new byte[1024];
			int i = 0;
			while ((i = di.read(b)) > 0) {
				fo.write(b, 0, i);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			if (fo != null) {
				fo.close();
				fo = null;
			}
			if (di != null) {
				di.close();
				di = null;
			}
			if (output != null) {
				output.close();
				output = null;
			}
		}

		// 还要检查图片文件大小和图片文件确定是否存在
		File file = new File(saveFileName);
		if (!file.exists() || !file.canRead() || !file.isFile() || file.length() <= 0) {
			return false;
		}

		return true;
	}

	/**
	 * 保存远程图片到本地
	 * 
	 * @param imgSrcUrl
	 * @param saveFileName
	 * @return
	 * @throws IOException
	 */
	public static boolean saveImage(String imgSrcUrl, String saveFileName) throws IOException {

		try {
			GetMethod getMethod = null;
			try {
				getMethod = new GetMethod();
				getMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, Constants.ENCODING_UTF8);
				getMethod.setURI(new URI(imgSrcUrl));
			} catch (Exception e) {
				imgSrcUrl = URLEncoder.encode(imgSrcUrl, Constants.ENCODING_UTF8);
				getMethod.setURI(new URI(imgSrcUrl));
				e.printStackTrace();
			}

			/*
			 * getMethod.addRequestHeader("User-Agent",
			 * JsoupUtil.getRandomUserAgent());
			 */
			new HttpClient().executeMethod(getMethod);
			new FileOutputStream(saveFileName).write(getMethod.getResponseBody());
			getMethod.releaseConnection();

			// 还要检查图片文件大小和图片文件确定是否存在
			File file = new File(saveFileName);
			if (!file.exists() || !file.canRead() || !file.isFile() || file.length() <= 0) {
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}

		return true;
	}

	/**
	 * 将HTTP资源另存为文件
	 * 
	 * @param destUrl
	 *            String
	 * @param fileName
	 *            String
	 * @return
	 * @throws Exception
	 */
	public static boolean saveToFile(String destUrl, String fileName) throws IOException {
		FileOutputStream fos = null;
		BufferedInputStream bis = null;
		HttpURLConnection httpUrl = null;

		URL url = null;
		byte[] buf = new byte[2048];
		int size = 0;

		// 建立链接
		url = new URL(destUrl);
		httpUrl = (HttpURLConnection) url.openConnection();
		/*
		 * httpUrl.setRequestProperty("User-Agent",
		 * JsoupUtil.getRandomUserAgent());
		 */
		// 连接指定的资源
		httpUrl.connect();
		// 获取网络输入流
		bis = new BufferedInputStream(httpUrl.getInputStream());
		// 建立文件
		fos = new FileOutputStream(fileName);

		// 保存文件
		while ((size = bis.read(buf)) != -1) {
			fos.write(buf, 0, size);
		}

		fos.close();
		bis.close();
		httpUrl.disconnect();

		return true;
	}

	public static boolean saveToPicture(String fileUrl, String savePath) throws IOException {
		try {
			URL url = new URL(fileUrl);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			DataInputStream in = new DataInputStream(connection.getInputStream());
			DataOutputStream out = new DataOutputStream(new FileOutputStream(savePath));
			byte[] buffer = new byte[4096];
			int count = 0;
			while ((count = in.read(buffer)) > 0) {
				out.write(buffer, 0, count);
			}
			out.close();
			in.close();
			connection.disconnect();
			return true;

		} catch (Exception e) {
			System.out.println(e + fileUrl + savePath);
			return false;
		}
	}

	// 读取图片
	public static byte[] readFileByBytes(String fileName) {
		InputStream in = null;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			in = new FileInputStream(fileName);
			byte[] buf = new byte[1024];
			int length = 0;
			while ((length = in.read(buf)) != -1) {
				out.write(buf, 0, length);
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e1) {
				}
			}
		}
		return out.toByteArray();
	}

	/**
	 * 下载
	 * 
	 * @param response
	 * @param path
	 *            文件路径和名称
	 * @param filename
	 *            下载时显示的名称
	 * @throws IOException
	 */
	public static void downloadImageForUrl(HttpServletResponse response, String imageUrl, String fileName)
			throws IOException {
		response.setContentType("application/OCTET-STREAM;charset=UTF-8");
		response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

		URL url = new URL(imageUrl);
		DataInputStream dis = null;

		try {
			dis = new DataInputStream(url.openStream());
			BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
			byte[] buffer = new byte[1024];
			int len;
			while ((len = dis.read(buffer)) != -1) {
				out.write(buffer, 0, len);
				out.flush();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public static void saveFile() {
		/*
		 * try { // 打开一个随机访问文件流，按读写方式 RandomAccessFile randomFile = new
		 * RandomAccessFile(file, "rw"); // 文件长度，字节数 long fileLength =
		 * randomFile.length(); // 将写文件指针移到倒数第n个字符。 randomFile.seek(fileLength -
		 * 8); randomFile.write(Utils.joinString(context,
		 * "\n</beans>").getBytes("UTF-8")); randomFile.close(); } catch
		 * (IOException e) { e.printStackTrace(); }
		 */
	}
	
	
	public static String byteToHexString(byte[] src) {
		if (null==src||src.length<=0) {
			return null;
		}
		String string="";
		for (byte b : src) {
			int v=b&0xFF;
			String hv=Integer.toHexString(v);
			if (hv.length()<2) {
				string=Utils.joinString(string,"0");
			}
			string=Utils.joinString(string,hv);
		}
		return string;
	}
	/**
	 * @description:根据文件流读取文件真正类型
	 * @author:     qinyingqin
	 * @date:       2015年5月19日 上午11:20:56
	 * @version:	v1.0 
	 */
	public static String getTypeByStream(InputStream is) {
		byte[] b=new byte[4];
		try {
			is.read(b,0,b.length);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String type=byteToHexString(b).toUpperCase();
		if ("504B0304".equals(type)) {
			return "zip";
		}
		return null;
	}
	
	/**
	 *校验2个文件内容是否相同
	 */
	public static boolean isSameContent(File file1, File file2) throws IOException {
		BufferedReader br1 = new BufferedReader(new InputStreamReader(
				new FileInputStream(file1)));
		BufferedReader br2 = new BufferedReader(new InputStreamReader(
				new FileInputStream(file2)));
		String content = br1.readLine();
		boolean same = false;
		while (content != null) {
			String content2 = br2.readLine();
			boolean b = (content == null);
			same = b ? content2 == null : content.equals(content2);
			content = br1.readLine();
			if(same==false){
				break;
			}
		}
			br1.close();
			br2.close();
		return same;
	}
	
	/**
	 *校验2个文件内容是否相同
	 *简单校验，只校验文件第一行数据
	 */
	public static boolean isSameContentSimp(File file1, File file2) throws IOException {
		BufferedReader br1 = new BufferedReader(new InputStreamReader(
				new FileInputStream(file1)));
		BufferedReader br2 = new BufferedReader(new InputStreamReader(
				new FileInputStream(file2)));
		String content = br1.readLine();
		boolean same = false;
		
		
		for (int i=0;i<100;i++) {
			String content2 = br2.readLine();
			boolean b = (content == null);
			same = b ? content2 == null : content.equals(content2);
			content = br1.readLine();
			if(same==false){
				break;
			}
		}
		
		br1.close();
		br2.close();
		return same;
	}
	
}
